# -*- coding:utf-8 -*-

import time
from functools import wraps

_profile = False
_records = {}

class Record(object):
    __slot__ = ('name', 'min', 'max', 'total')

    def __init__(self, side, name):
        self.side = side
        self.name = name
        self.times = 0
        self.total = 0.0

    def __hash__(self):
        return hash(self.name)

    def __str__(self):
        avg = 0.0 if not self.times else self.total / self.times
        return '%s\t%s\t%s\t%s\t%s\t%s' % (
                self.side, self.name, self.times, self.min, avg, self.max)

    def calc(self, new_value):
        if self.times <= 0:
            self.min = self.max = self.total = new_value
            self.times = 1
            return
        if self.min > new_value:
            self.min = new_value
        if self.max < new_value:
            self.max = new_value
        self.total += new_value
        self.times += 1

def set_profile(yes):
    global _profile
    _profile = yes

def get_profile():
    global _profile
    return _profile

def profile_callmethod(method_fullname):
    def f(func):
        @wraps(func)
        def _func(*a, **kw):
            if not _profile:
                return func(*a, **kw)
            global _records
            bgn = time.clock()
            try:
                return func(*a, **kw)
            finally:
                try:
                    rec = _records[method_fullname]
                except KeyError:
                    rec = Record('client', method_fullname)
                    _records[method_fullname] = rec
                rec.calc(time.clock() - bgn)
        return _func
    return f

def profile_process_request(func):
    pass

def dump_profile(output = None):
    global _records
    if not _records:
        return
    if not output:
        import sys
        output = sys.stdout
    print >>output, '\n'.join(map(str, _records.itervalues()))

